#ifndef __FAN_MOTOR_DRIVER_H__
#define __FAN_MOTOR_DRIVER_H__

typedef struct _GPIOx
{                                  // offset
    volatile unsigned int MODER;   // 0x00
    volatile unsigned int OTYPER;  // 0x04
    volatile unsigned int OSPEEDR; // 0x08
    volatile unsigned int PUPDR;   // 0x0C
    volatile unsigned int IDR;     // 0x10
    volatile unsigned int ODR;     // 0x14
    volatile unsigned int BSRR;    // 0x18
    volatile unsigned int LCKR;    // 0x1C
    volatile unsigned int AFRL;    // 0x20
    volatile unsigned int AFRH;    // 0x24
    volatile unsigned int BRR;     // 0x28
    volatile unsigned int res;
    volatile unsigned int SECCFGR; // 0x30
} GPIOx_t;
typedef struct
{
    volatile unsigned int CR1;
    volatile unsigned int CR2;
    volatile unsigned int SMCR;
    volatile unsigned int DIER;
    volatile unsigned int SR;
    volatile unsigned int EGR;
    volatile unsigned int CCMR1;
    volatile unsigned int CCMR2;
    volatile unsigned int CCER;
    volatile unsigned int CNT;
    volatile unsigned int PSC;
    volatile unsigned int ARR;
    volatile unsigned int RCR;
    volatile unsigned int CCR1;
    volatile unsigned int CCR2;
    volatile unsigned int CCR3;
    volatile unsigned int CCR4;
    volatile unsigned int BDTR;
    volatile unsigned int DCR;
    volatile unsigned int DMAR;
    volatile unsigned int Res1;
    volatile unsigned int CCMR3;
    volatile unsigned int CCR5;
    volatile unsigned int CCR6;
    volatile unsigned int AF1;
    volatile unsigned int AF2;
    volatile unsigned int TISEL;
} TIM1_t;
typedef struct
{
    volatile unsigned int CR1;
    volatile unsigned int CR2;
    volatile unsigned int SMCR;
    volatile unsigned int DIER;
    volatile unsigned int SR;
    volatile unsigned int EGR;
    volatile unsigned int CCMR1;
    volatile unsigned int CCMR2;
    volatile unsigned int CCER;
    volatile unsigned int CNT;
    volatile unsigned int PSC;
    volatile unsigned int ARR;
    volatile unsigned int RES1[1];
    volatile unsigned int CCR1;
    volatile unsigned int CCR2;
    volatile unsigned int CCR3;
    volatile unsigned int CCR4;
    volatile unsigned int RES2[1];
    volatile unsigned int DCR;
    volatile unsigned int DMAR;
    volatile unsigned int RES3[4];
    volatile unsigned int AF1;
    volatile unsigned int RES4[1];
    volatile unsigned int TISEL;
} TIM2_3_4_5_t;
typedef struct
{
    volatile unsigned int CR1;
    volatile unsigned int CR2;
    volatile unsigned int RES1;
    volatile unsigned int DIER;
    volatile unsigned int SR;
    volatile unsigned int EGR;
    volatile unsigned int CCMR1;
    volatile unsigned int RES2;
    volatile unsigned int CCER;
    volatile unsigned int CNT;
    volatile unsigned int PSC;
    volatile unsigned int ARR;
    volatile unsigned int RCR;
    volatile unsigned int CCR1;
    volatile unsigned int RES3[3];
    volatile unsigned int BDTR;
    volatile unsigned int DCR;
    volatile unsigned int DMAR;
    volatile unsigned int RES4[4];
    volatile unsigned int AF1;
    volatile unsigned int RES5;
    volatile unsigned int TISEL;
} TIM16_17_t;

#define GPIOE_TRUTH_ADDR 0x50006000
#define GPIOF_TRUTH_ADDR 0x50007000

#define TIM1_TRUTH_ADDR 0x44000000
#define TIM2_TRUTH_ADDR 0x40000000
#define TIM3_TRUTH_ADDR 0x40001000
#define TIM4_TRUTH_ADDR 0x40002000
#define TIM5_TRUTH_ADDR 0x40003000
#define TIM16_TRUTH_ADDR 0x44007000
#define TIM17_TRUTH_ADDR 0x44008000

#define RCC_AHB4_SET_EN_TRUTH_ADDR 0x50000A28
#define RCC_APB2_SET_EN_TRUTH_ADDR 0x50000A08

enum _motor_control
{
    motor_off = 0,
    motor_1, // 速度1
    motor_2, // 2
    motor_3, // 3
    motor_on,
};
enum _fan_control
{
    fan_off = 0,
    fan_1, // 速度1
    fan_2, // 2
    fan_3, // 3
    fan_on,
};

#define GET_SIZE_FROM_CMD(cmd) ({ \
    int res;                      \
    res = ((cmd >> 16) & 0x3FFF); \
    res;                          \
})

#define GET_FUNC_FROM_CMD(cmd) ({ \
    int res;                      \
    res = cmd & 0xFF;             \
    res;                          \
})

#define MOTOR_IOWR(x) (_IOWR('F', x, int))
#define FAN_IOWR(x) (_IOWR('F', x, int))

#endif